<template>
  <div class="map-view" ref="container">
    <div
      class="app-box"
      :style="{ width: mapReact.width + 'px', height: mapReact.height + 'px' }"
    >
      <div
        class="map"
        id="mapDiv"
        ref="mapDiv"
        :style="{
          width: mapReact.width + 'px',
          height: mapReact.height + 'px',
        }"
      ></div>
      <div class="layers">
        <div class="mark-title">
          <div class="mark-name">协同标绘主题：{{ plotTitle }}</div>
        </div>
        <div class="mapTools">
          <div class="tools" v-if="toolBoxShow">
            <ul>
              <li>
                <el-button class="tool-btn" @click="selectTool(1)">
                  <i class="el-icon-full-screen" />
                  <div class="btn-text">矩形</div>
                </el-button>
              </li>
              <li>
                <el-button class="tool-btn" @click="selectTool(2)">
                  <i class="el-icon-picture-outline-round" />
                  <div class="btn-text">圆形</div>
                </el-button>
              </li>
              <li>
                <el-button class="tool-btn" @click="selectTool(3)">
                  <i class="el-icon-collection-tag" />
                  <div class="btn-text">多边形</div>
                </el-button>
              </li>
              <li>
                <el-button class="tool-btn" @click="selectTool(4)">
                  <i class="el-icon-s-opportunity" />
                  <div class="btn-text">标记</div>
                </el-button>
              </li>
            </ul>
          </div>
          <el-button class="tool-btn" @click="toolBoxShow = !toolBoxShow">
            <i class="el-icon-suitcase-1" />
            <div class="btn-text">标绘工具</div>
          </el-button>
        </div>
        <div class="online-users">
          <div class="header">在线标绘人员</div>
          <ul>
            <li v-for="user in onlineUsers" :key="user.userId">
              <div class="mark-user">
                <div class="user-face"><img :src="user.avatar" /></div>
                <div class="user-name">{{ user.nickName }}</div>
              </div>
            </li>
          </ul>
        </div>
      </div>
    </div>
    <el-dialog
      title="标记说明"
      :visible.sync="markTipShow"
      width="400px"
      append-to-body
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="false"
    >
      <el-form :model="form" label-width="100" :inline="true">
        <el-form-item label="标记点说明">
          <el-row>
            <el-col :span="24">
              <el-input
                type="textarea"
                v-model="form.name"
                autocomplete="off"
              ></el-input>
            </el-col>
          </el-row>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="setMarkTip">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import mapMixin from "@/mixins/lfMapMixin";
import * as OAApi from "@/api/oa/oa";

export default {
  name: "SynMark",
  mixins: [mapMixin],
  data() {
    return {
      mapReact: {
        width: 0,
        height: 0,
      },
      toolBoxShow: false,
      markTipShow: false,
      form: {
        name: "",
      },
      toolType: 0,
      datas: [],
      ws: null,
      newLayer: null,
      plotId: 0,
      userId: 0,
      plotTitle: "",
      heartbeatTimer: null,
      onlineUsers: [],
    };
  },
  mounted() {
    this.userId = this.$store.state.user.userId;
    this.plotId = this.$route.query.plotId;
    this.resetWindowReact();
    this.init();
  },
  methods: {
    resetWindowReact() {
      let mapView = document.getElementsByClassName("map-view")[0];
      const mapViewHeight = mapView.parentNode.clientHeight;
      const mapViewWidth = mapView.parentNode.clientWidth;
      this.mapReact = {
        width: mapViewWidth,
        height: mapViewHeight,
      };
    },
    init() {
      this.$nextTick(() => {
        if (!this.map) {
          this.initMap();
          // 获取标绘详情
          this.getSynMarkerInfo();
          // 获取历史数据
          this.getHistoryMarkers();
        }
      });
    },
    getSynMarkerInfo() {
      OAApi.getSynMarkerInfo(this.plotId).then((res) => {
        this.plotTitle = res.data.plottingTitle;
      });
    },
    getHistoryMarkers() {
      OAApi.getHistoryMarkers(this.plotId).then((res) => {
        console.log(res);
        let data = res.data;
        let markers = [];
        data.forEach((item) => {
          let markData = {
            id: item.plottingPointId,
            type: item.type,
            pathData: item.data,
            tip: item.label,
            nickName: item.userName,
            userId: item.userId,
          };
          markers.push(markData);
        });
        this.clearDraw();
        this.datas = markers;
        this.drawOtherLayer();
        if (this.ws == null) {
          this.initWebSocket();
        }
      });
    },
    drawOtherLayer() {
      this.datas.forEach((item) => {
        this.drawDataToMap(item);
      });
    },
    drawDataToMap(data) {
      let colors = ["#3388ff", "#E6A23C", "#F56C6C", "#CC9966", "#FF6600"];
      let drawColor = data.userId == this.userId ? colors[0] : colors[2];
      let pathData = JSON.parse(data.pathData);
      var layer = null;
      switch (data.type) {
        case 1: //矩形
          layer = L.rectangle(pathData.path, {
            color: drawColor,
          }).addTo(this.map);
          break;
        case 2: //圆形
          layer = L.circle(pathData.path, {
            radius: pathData.radius,
            color: drawColor,
          }).addTo(this.map);
          break;
        case 3: //多边形
          layer = L.polygon(pathData.path, {
            color: drawColor,
          }).addTo(this.map);
          break;
        case 4: //标记点
          layer = L.marker(pathData.path).addTo(this.map);
          break;
      }
      layer.bindTooltip(`${data.nickName}：${data.tip}`, {
        permanent: true,
      });
      layer.on("dblclick", (ev) => {
        this.onLayerDoubleClick(ev, data.id);
      });
      this.layer.push(layer);
    },
    selectTool(type) {
      this.toolType = type;
      // 开启对应工具
      switch (type) {
        case 3: // 多边形
          this.drawPolygon();
          break;
        case 2: // 圆
          this.drawCircle();
          break;
        case 1: // 矩形
          this.drawRectangle();
          break;
        case 4: // 标记点
          // this.drawSector();
          this.drawMarker();
          break;
      }
    },
    drawMarker() {
      this.map.on("click", (e) => {
        let marker = this.addMarker([e.latlng.lat, e.latlng.lng]);
        this.layer.push(marker);
        this.onDrawEndEvent(marker);
        this.map.off("click");
      });
    },
    onDrawEndEvent(layer) {
      this.newLayer = layer;
      // 弹出框回填标题
      this.markTipShow = true;
    },
    onLayerDoubleClick(ev, id) {
      // layer双击事件，默认为删除操作
      this.$modal.confirm("是否需要删除该标绘？").then(() => {
        this.handleDelMarker(id);
      });
      L.DomEvent.stopPropagation(ev);
    },
    setMarkTip() {
      if (this.form.name == "") {
        this.$modal.msgError("请填写标记点说明");
        return false;
      }
      this.markTipShow = false;
      let userName = this.$store.state.user.nickname;
      this.layer[this.layer.length - 1].bindTooltip(
        userName + "：" + this.form.name,
        {
          permanent: true,
        }
      );
      // 发送到服务端
      this.sendLayerDataToServer();
      this.form.name = "";
      this.toolType = 0;
    },
    initWebSocket() {
      const uid = this.$store.state.user.userId;
      const wsuri =
        "ws://192.168.31.40:8080/aero/oa/sysMarker/" + this.plotId + "/" + uid;
      this.ws = new WebSocket(wsuri);
      this.ws.onopen = (event) => {
        // 建立连接
        this.heartbeatStart();
        this.getOnlineUsers();
      };
      this.ws.onmessage = (event) => {
        console.log(event.data);
        let msgData = JSON.parse(event.data);
        switch (msgData.msgType) {
          case 2:
            // 新标绘
            let msgContent = msgData.msgContent;
            let markData = {
              id: msgContent.plottingPointId,
              type: msgContent.type,
              pathData: msgContent.data,
              tip: msgContent.label,
              nickName: msgContent.userName,
              userId: msgContent.userId,
            };
            this.datas.push(markData);
            this.drawDataToMap(markData);
            break;
          case 999:
            // 标绘发送成功
            this.datas[this.datas.length - 1].id = msgData.msgContent;
            this.layer[this.layer.length - 1].on("dblclick", (ev) => {
              this.onLayerDoubleClick(ev, msgData.msgContent);
            });
            break;
          case 3:
            // 新成员加入
            this.getOnlineUsers();
            break;
          case 4:
            // 新成员退出
            this.getOnlineUsers();
            break;
          case 5:
            // 踢下线
            this.$modal
              .confirm(
                "您打开了另一个协同标绘场景，当前场景已停止同步，是否刷新"
              )
              .then(() => {
                window.location.reload();
              });
            break;
          case 6:
            // 标记点删除
            this.getHistoryMarkers();
            break;
        }
      };
      this.ws.onclose = (event) => {
        // 关闭连接
        clearInterval(this.heartbeatTimer);
      };
    },
    heartbeatStart() {
      this.heartbeatTimer = setInterval(() => {
        this.ws.send(JSON.stringify({ msgType: 1 }));
      }, 3 * 1000);
    },
    getOnlineUsers() {
      OAApi.getSynMarkerUsers(this.plotId).then((res) => {
        let users = [];
        res.data.forEach((user) => {
          users.push({
            userId: user.userId,
            nickName: user.nickName,
            avatar: process.env.VUE_APP_BASE_API + user.avatar,
          });
        });
        this.onlineUsers = users;
      });
    },
    sendLayerDataToServer() {
      const uid = this.$store.state.user.userId;
      var sendContent = {
        plottingId: this.plotId,
        type: this.toolType,
        data: [],
        label: this.form.name,
        userId: uid,
      };

      switch (this.toolType) {
        case 3: // 多边形
          let points = [];
          this.newLayer._latlngs[0].forEach((l) => {
            points.push([l.lat, l.lng]);
          });
          sendContent.data = JSON.stringify({ path: points });
          break;
        case 2: // 圆
          sendContent.data = JSON.stringify({
            path: [this.newLayer._latlng.lat, this.newLayer._latlng.lng],
            radius: this.newLayer._mRadius,
          });
          break;
        case 1: // 矩形
          sendContent.data = JSON.stringify({
            path: [
              [
                this.newLayer._bounds._northEast.lat,
                this.newLayer._bounds._northEast.lng,
              ],
              [
                this.newLayer._bounds._southWest.lat,
                this.newLayer._bounds._southWest.lng,
              ],
            ],
          });
          break;
        case 4: // 标记点
          sendContent.data = JSON.stringify({
            path: [this.newLayer._latlng.lat, this.newLayer._latlng.lng],
          });
          break;
      }
      this.ws.send(JSON.stringify({ msgType: 2, msgContent: sendContent }));
    },
    handleDelMarker(id) {
      OAApi.delMarker(id).then((res) => {
        this.$modal.msgSuccess("标绘点删除成功");
        this.getHistoryMarkers();
      });
    },
  },
  beforeDestroy() {
    this.ws.close();
  },
};
</script>
<style lang="scss" scoped>
ul {
  padding: 0;
  margin: 0;
}

li {
  list-style: none;
}

.map-view {
  position: relative;
}

#mapDiv {
  width: 100%;
  position: absolute;
  z-index: 0;
}

.app-box {
  position: absolute;
  left: 0;
  top: 0;
  box-sizing: content-box;
}

.layers {
  position: absolute;
  width: 100%;
  top: 0;
  left: 0;
  z-index: 2001;

  .mark-title {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 20px 0;

    .mark-name {
      background-color: white;
      border-radius: 10px;
      color: #0489dd;
      font-size: 20px;
      font-weight: bold;
      padding: 0 20px;
      text-align: center;
      height: inherit;
      line-height: 40px;
      box-shadow: 0 5px 1px #ccc;
    }
  }

  .mapTools {
    position: absolute;
    min-width: 60px;
    height: 60px;
    top: 60px;
    right: 30px;
    z-index: 9999;
    justify-content: space-between;
    display: flex;
    flex-flow: row;

    .tools {
      margin-right: 20px;

      ul {
        display: flex;
        flex-flow: row;

        li {
          margin-right: 10px;

          &:last-child {
            margin-right: 0;
          }
        }
      }

      .tool-btn {
        border: 0;
        border-radius: 5px;
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 13px;
        padding: 0;
        width: 60px;
        height: 60px;
        background-color: #fff;
      }

      .tool-btn:hover {
        cursor: pointer;
      }

      .tool-btn i {
        font-size: 22px;
        margin-bottom: 5px;
      }
    }
  }

  .online-users {
    position: absolute;
    min-width: 130px;
    top: 140px;
    right: 30px;
    z-index: 9999;
    justify-content: space-between;
    display: flex;
    flex-flow: column;
    background-color: white;
    font-size: 12px;

    .header {
      line-height: 30px;
      height: 30px;
      font-size: 14px;
      border-bottom: 1px solid #ccc;
      padding: 0 10px;
    }

    ul {
      margin-top: 10px;
      margin-bottom: 10px;
    }

    .mark-user {
      display: flex;
      flex-flow: row;
      height: 30px;
      line-height: 30px;
      padding: 0 10px;

      .user-face {
        width: 24px;
        height: 24px;
        margin-top: 3px;
        border-radius: 12px;
        overflow: hidden;
        margin-right: 10px;

        img {
          width: inherit;
          height: inherit;
        }
      }
    }
  }
}

ul,
li {
  margin: 0;
  padding: 0;
}

li {
  list-style: none;
}
</style>
